package cn.sylinx.common.ext.vertx;

import java.util.Optional;

import cn.sylinx.common.ext.log.GLog;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Handler;
import io.vertx.core.eventbus.Message;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

/**
 * 单个verticle处理单个事件
 * 
 * @author han
 *
 */
public abstract class BaseVerticle extends AbstractVerticle implements Handler<Message<JsonObject>> {

	protected JsonObject config;

	public void start() {
		config = context.config();
		afterStart();
		vertx.eventBus().consumer(getEventAddress(), this);
	}

	protected abstract String getEventAddress();

	public void afterStart() {
	}

	public void afterStop() {
	}

	@Override
	public void stop() {

		try {
			super.stop();
		} catch (Exception e) {
			GLog.error("BaseVerticle stop error: {} ", e);
		}
		afterStop();
	}

	protected void sendOK(Message<JsonObject> message) {
		sendOK(message, null);
	}

	protected void sendStatus(String status, Message<JsonObject> message) {
		sendStatus(status, message, null);
	}

	protected void sendStatus(String status, Message<JsonObject> message, JsonObject json) {
		if (json == null) {
			json = new JsonObject();
		}
		json.put("status", status);
		message.reply(json);
	}

	protected void sendOK(Message<JsonObject> message, JsonObject json) {
		sendStatus("ok", message, json);
	}

	protected void sendError(Message<JsonObject> message, String error) {
		sendError(message, error, null);
	}

	protected void sendError(Message<JsonObject> message, String error, Exception e) {
		JsonObject json = new JsonObject().put("status", "error").put("message", error);
		message.reply(json);
	}

	protected String getMandatoryString(String field, Message<JsonObject> message) {
		String val = message.body().getString(field);
		if (val == null) {
			sendError(message, field + " must be specified");
		}
		return val;
	}

	protected JsonObject getMandatoryObject(String field, Message<JsonObject> message) {
		JsonObject val = message.body().getJsonObject(field);
		if (val == null) {
			sendError(message, field + " must be specified");
		}
		return val;
	}

	protected boolean getOptionalBooleanConfig(String fieldName, boolean defaultValue) {
		return Optional.ofNullable(config.getBoolean(fieldName)).orElse(defaultValue);
	}

	protected String getOptionalStringConfig(String fieldName, String defaultValue) {
		return Optional.ofNullable(config.getString(fieldName)).orElse(defaultValue);
	}

	protected int getOptionalIntConfig(String fieldName, int defaultValue) {
		return Optional.ofNullable(config.getInteger(fieldName)).orElse(defaultValue);
	}

	protected long getOptionalLongConfig(String fieldName, long defaultValue) {
		return Optional.ofNullable(config.getLong(fieldName)).orElse(defaultValue);
	}

	protected JsonObject getOptionalObjectConfig(String fieldName, JsonObject defaultValue) {
		return Optional.ofNullable(config.getJsonObject(fieldName)).orElse(defaultValue);
	}

	protected JsonArray getOptionalArrayConfig(String fieldName, JsonArray defaultValue) {
		return Optional.ofNullable(config.getJsonArray(fieldName)).orElse(defaultValue);
	}

	protected boolean getMandatoryBooleanConfig(String fieldName) {
		Boolean b = config.getBoolean(fieldName);
		if (b == null) {
			throw new IllegalArgumentException(fieldName + " must be specified in config for busmod");
		}
		return b;
	}

	protected String getMandatoryStringConfig(String fieldName) {
		String s = config.getString(fieldName);
		if (s == null) {
			throw new IllegalArgumentException(fieldName + " must be specified in config for busmod");
		}
		return s;
	}

	protected int getMandatoryIntConfig(String fieldName) {
		Number i = config.getInteger(fieldName);
		if (i == null) {
			throw new IllegalArgumentException(fieldName + " must be specified in config for busmod");
		}
		return i.intValue();
	}

	protected long getMandatoryLongConfig(String fieldName) {
		Number l = config.getLong(fieldName);
		if (l == null) {
			throw new IllegalArgumentException(fieldName + " must be specified in config for busmod");
		}
		return l.longValue();
	}

}
